home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / grafik / raytracing / rayshade-4.0.6.3 / libshade / lightdef.c < prev    next >
C/C++ Source or Header  |  1994-08-09  |  4KB  |  153 lines

  1. /*
  2.  * lightdef.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * lightdef.c,v 4.1 1994/08/09 08:04:31 explorer Exp
  17.  *
  18.  * lightdef.c,v
  19.  * Revision 4.1  1994/08/09  08:04:31  explorer
  20.  * Bump version to 4.1
  21.  *
  22.  * Revision 1.1.1.1  1994/08/08  04:52:16  explorer
  23.  * Initial import.  This is a prerelease of 4.0.6enh3, or 4.1 possibly.
  24.  *
  25.  * Revision 4.0  91/07/17  14:46:25  kolb
  26.  * Initial version.
  27.  * 
  28.  */
  29. #include "rayshade.h"
  30. #include "options.h"
  31. #include "liblight/light.h"
  32. #include "liblight/infinite.h"    /* to create default infinite light */
  33. #include "liblight/jittered.h"    /* to create jittered light sources */
  34.  
  35. Light *Lights = NULL;        /* Linked list of defined lights */
  36.  
  37. void
  38. LightAddToDefined(light)
  39. Light *light;
  40. {
  41.     if (light) {
  42.         light->next = Lights;
  43.         Lights = light;
  44.     }
  45. }
  46.  
  47. void
  48. LightSetup()
  49. {
  50.     long shadowopts;
  51.     Light *ltmp;
  52.  
  53.     /*
  54.      * Set shadowing options.
  55.      */
  56.     shadowopts = 0;
  57.     if (Options.no_shadows)
  58.         shadowopts |= SHADOW_NONE;
  59.     if (Options.shadowtransp)
  60.         shadowopts |= SHADOW_TRANSP;
  61.     if (Options.csg)
  62.         shadowopts |= SHADOW_CSG;
  63.     if (Options.cache)
  64.         shadowopts |= SHADOW_CACHE;
  65.     if (Options.shutterspeed > 0.)
  66.         shadowopts |= SHADOW_BLUR;
  67.     ShadowSetOptions(shadowopts);
  68.  
  69.     /*
  70.      * If no light sources were defined, add a default.
  71.      */
  72.     if (Lights == (Light *)NULL) {
  73.         Color ctmp;
  74.         Vector vtmp;
  75.         vtmp.x = vtmp.z = 1.;
  76.         vtmp.y = -1;
  77.         ctmp.r = ctmp.g = ctmp.b = 1.;
  78.  
  79.         LightAddToDefined(LightInfiniteCreate(&ctmp, &vtmp));
  80.     }
  81.     /*
  82.      * Now that we've parsed the input file, we know what
  83.      * maxlevel is, and we can allocate the correct amount of
  84.      * space for each light source's cache.
  85.      */
  86.     for (ltmp = Lights; ltmp; ltmp = ltmp->next) {
  87.         ltmp->cache = (ShadowCache *)Calloc(
  88.             (unsigned)Options.maxdepth + 1, sizeof(ShadowCache));
  89.     }
  90. }
  91.  
  92. void
  93. AreaLightCreate(color, corner, u, usamp, v, vsamp, shadow)
  94. Color *color;
  95. Vector *corner, *u, *v;
  96. int usamp, vsamp, shadow;
  97. {
  98.     Vector vpos, curpos;
  99.     int i, j, numlight;
  100.     Float ulen, vlen;
  101.     Color intens;
  102.     Light *ltmp;
  103.  
  104.     if (usamp < 1 || vsamp < 1)
  105.         RLerror(RL_ABORT, "Invalid area light specification.\n");
  106.  
  107.     numlight = usamp * vsamp;    /* Total number of jittered sources */
  108.  
  109.     /*
  110.      * Sum of all intensities is equal to specified intensity.
  111.      */
  112.     intens.r = color->r / (Float)numlight;
  113.     intens.g = color->g / (Float)numlight;
  114.     intens.b = color->b / (Float)numlight;
  115.  
  116.     VecSub(*u, *corner, u);
  117.     VecSub(*v, *corner, v);
  118.     /*
  119.      * Make sure that u and v are not degenerate.
  120.      */
  121.     ulen = VecNormalize(u);
  122.     vlen = VecNormalize(v);
  123.     if (ulen < EPSILON || vlen < EPSILON)
  124.         RLerror(RL_ABORT, "Degenerate area light source.\n");
  125.     /*
  126.      * Scale u and v such that they define the area covered by a
  127.      * single sample.
  128.      */
  129.     VecScale(ulen / (Float)usamp, *u, u); 
  130.     VecScale(vlen / (Float)vsamp, *v, v);
  131.     /*
  132.      * For each sample...
  133.      */
  134.     vpos = *corner;
  135.     for (i = 0; i < vsamp; i++) {
  136.         curpos = vpos;
  137.         for (j = 0; j < usamp; j++) {
  138.             /*
  139.              * current pos is the "corner" of a new light
  140.              * source.  A jittered position based on
  141.              * the "corner" and the two edge vectors
  142.              * is used as the position for the
  143.              * light source in lighting calculations.
  144.              */
  145.             ltmp = LightJitteredCreate(&intens, &curpos, u, v);
  146.             ltmp->shadow = shadow;
  147.             LightAddToDefined(ltmp);
  148.             VecAdd(curpos, *u, &curpos);
  149.         }
  150.         VecAdd(vpos, *v, &vpos);
  151.     }
  152. }
  153.